-- | Module:        Hexena.Internal.SVMWitchcraft
--   Stability:     Experimental
--   Portability:   Portable
--
--   Internal-Use module.  This module exports variables and functions that 
--   are considered not for public consumption.  As such with all internal-use 
--   modules.  The variables contained are considered to be in flux and may 
--   be changed at any time as the project unfolds.  Developers use contents
--   contained herein at your own risk.
module Hexena.Internal.SVMWitchcraft
	( Model
	, loadModel
	, predict
	) where

import Control.Arrow ((***))
import qualified Data.IntMap as IM
import Foreign
import Foreign.C
import Bindings.SVM

newtype Model = Model (Ptr C'svm_model)
type Vector = IM.IntMap Double

loadModel :: String -> IO (Maybe Model)
loadModel fn = do
  x <- withCString fn c'svm_load_model
  return $ if x == nullPtr then Nothing else Just $ Model x

predict :: Model -> Vector -> IO Double
predict (Model m) xs = let eoa = C'svm_node (-1) 0
                           con = uncurry C'svm_node . (fromIntegral *** realToFrac)
                           arr' = map con $ IM.assocs xs
                           arr = arr' ++ [eoa]
                       in realToFrac `fmap` withArray arr (c'svm_predict m)